package com.loe.ui

import android.app.Application
import android.content.pm.ApplicationInfo
import android.util.Log
import com.loe.http.LoeHttp
import com.loe.logger.LoeLogger
import com.loe.mvp.BaseView
import com.loe.mvp.ext_app.XIntent
import com.loe.mvp.ext_java.safe
import com.loe.mvp.util.sp.SpDelegate
import com.loe.ui.quickjs.initAPI
import com.quickjs.JSContext
import com.quickjs.QuickJS

lateinit var jsEngine: QuickJS
    private set
lateinit var jsContext: JSContext
    private set

/** 存储 */
object UiSpMain : SpDelegate()
{
    var md5 by string()

    var packJs by string()

    var lastTestTime by long()
}

/** 用户存储 */
object UiSp : SpDelegate()

object LoeUI
{
    /** 预览模式（忽略版本号，底部显示控制台） */
    var isPreview = false
        private set

    /** JS资源地址 */
    private var uiUrl = ""

    /** 检测间隔 */
    private var TEST_DURATION = 10 * 60_000

    private var md5 = ""

    private const val packJsName = "pack.js"

    /** 是否测试版本 */
    var isDebug = false
        private set

    lateinit var app: Application

    private var lock = false

    /** 初始化LoeUI */
    fun init(app: Application, uiUrl: String, isPreview: Boolean = false)
    {
        this.uiUrl = uiUrl
        this.isPreview = isPreview
        this.app = app
        isDebug = app.applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE != 0
        if (isDebug) TEST_DURATION = 30_000

        // *************** 库初始化 **************
        LoeLogger.init(app, !isDebug)
        LoeHttp.init(app)
        // *************************************

        UiSpMain.init(app)
        UiSp.init(app)
        jsEngine = QuickJS.createRuntime()
        jsContext = jsEngine.createContext().initAPI()
        safe { jsContext.executeScript(UiSpMain.packJs, packJsName) }
    }

    /** 检测更新 */
    fun testLoadPackJs(ok: ((isNew: Boolean) -> Unit)? = null)
    {
        if (lock) return
        // 检测间隔限制
        if ((System.currentTimeMillis() - UiSpMain.lastTestTime) < TEST_DURATION)
        {
            return
        }
        loadPackJs(ok)
    }

    /** 加载js */
    fun loadPackJs(ok: ((isNew: Boolean) -> Unit)? = null)
    {
        lock = true
        // 加载md5
        LoeHttp.get("$uiUrl$packJsName.md5")
            .error { lock = false }
            .okString()
            {
                md5 = it
                // 有更新
                if (md5 != UiSpMain.md5)
                {
                    // 加载新pack.js
                    LoeHttp.get(uiUrl + packJsName)
                        .error { lock = false }
                        .okString()
                        {
                            safe()
                            {
                                Log.d("runtime", "${packJsName}加载成功")
                                jsContext.executeScript(it, packJsName)
                                UiSpMain.packJs = it
                                UiSpMain.md5 = md5
                                UiSpMain.lastTestTime = System.currentTimeMillis()
                                ok?.invoke(true)
                            }
                            lock = false
                        }
                } else
                {
                    // 沿用老pack.js
                    UiSpMain.lastTestTime = System.currentTimeMillis()
                    ok?.invoke(false)
                    lock = false
                }
            }
    }

    /** 打开Url监听 */
    var onOpenUrl: ((base: BaseView, urlString: String) -> XIntent)? = null
        private set

    fun setOnOpenUrl(onOpenUrl: (base: BaseView, urlString: String) -> XIntent)
    {
        this.onOpenUrl = onOpenUrl
    }
}